package algorithm.sort.array;

import java.util.Random;

/**
 * @program: algorithm-data-structure
 * @description: collect different sort method running time by sorting a loong int array.
 * @author: Keyu Li
 * @create: 2021-08-30 09:14
 **/


public class CompareSortMethod {
    final static int ARRAY_LENGTH = 100000;
    final static int ARRAY_INT_RANGE = ARRAY_LENGTH/10;
    final static int SORT_METHOD_NUMBER = 6;
    final static int SORT_LOOP = 5;

    public static void main(String[] args) {
        //create a int array using random.
        int[] arrOrigin = createArray();
        int[] arrCopy;

        // calculate time
        long startTime;
        long endTime;
        int[] sortTime = new int[SORT_METHOD_NUMBER];

        // store sort method
        SortingMethod[] sortMethod = new SortingMethod[SORT_METHOD_NUMBER];
        sortMethod[0] = new SortBubble();
        sortMethod[1] = new SortInsertion();
        sortMethod[2] = new SortSelection();
        sortMethod[3] = new SortMerge();
        sortMethod[4] = new SortQuick();
        sortMethod[5] = new SortHeap();

        for (int i = 0; i < SORT_LOOP; i++) {
            arrCopy = copyArray(arrOrigin);
//            System.out.println(sortMethod[i]);
//            System.out.println(sortSucceedTime(arrCopy, 0));
            startTime = System.currentTimeMillis();
            sortMethod[i].sort(arrCopy);
            endTime = System.currentTimeMillis();
            sortTime[i] = sortSucceedTime(arrCopy, (int)(endTime - startTime));
        }

        // Print sorting method and its time usage.
        printSoringTime(sortMethod, sortTime);
    }

    private static void printSoringTime(SortingMethod[] methods, int[] time) {
        System.out.println("int array size is: " + ARRAY_LENGTH);
        for (int i = 0; i < SORT_LOOP; i++) {
            System.out.print(methods[i].getName() + "\t");
        }
        System.out.println();
        for (int i = 0; i < SORT_LOOP; i++) {
            System.out.print(time[i] + "\t\t");
        }
        System.out.println();
    }

    // create a random int array
    public static int[] createArray() {
        int[] arr = new int[ARRAY_LENGTH];
        Random rd = new Random(10 * ARRAY_LENGTH);
        for (int i = 0; i < ARRAY_LENGTH; i++) {
            arr[i] = rd.nextInt(ARRAY_INT_RANGE);
//            System.out.println(arr[i]);
        }
        return arr;
    }

    // copy the origin random array.
    public static int[] copyArray(int[] arrOrigin) {
        int[] arrCopy = new int[arrOrigin.length];
        for (int i = 0; i < arrOrigin.length; i++) {
            arrCopy[i] = arrOrigin[i];
        }
        return arrCopy;
    }

    // if sort succeed, then return sort time; else, return -1.
    public static int sortSucceedTime(int[] arr, int time) {
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] < arr[i - 1])
                return -1;
        }
        return (int)time;
    }
}
